//Copyright (c) 2024 Deng Zicheng
//        "CarController" is licensed under Mulan PSL v2.
//        You can use this software according to the terms and conditions of the Mulan PSL v2.
//        You may obtain a copy of Mulan PSL v2 at:
//        http://license.coscl.org.cn/MulanPSL2
//        THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//        See the Mulan PSL v2 for more details.
package com.sinan.myapplication;

import ohos.bluetooth.ProfileBase;
import ohos.bluetooth.ble.*;

import javax.net.ssl.SSLContext;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


// 实现外围设备操作回调
public class MyBlePeripheralCallback extends BlePeripheralCallback {

    private final BlePeripheralDevice peripheralDevice;

    private  GattService service;

    private static final String SERVICE_UUID="0000ffe0-0000-1000-8000-00805f9b34fb";
    private static final String READ_WRITE_NOTIFY="0000ffe1-0000-1000-8000-00805f9b34fb";

    private final Pattern r = Pattern.compile("<(.*?)>");
    private static String messages="";

    public MyBlePeripheralCallback(BlePeripheralDevice peripheralDevice){
        this.peripheralDevice=peripheralDevice;
    }


    /**
     * 连接状态改变事件回调
     * @param connectionState 连接状态
     */
    @Override
    public void connectionStateChangeEvent(int connectionState) {
        if (connectionState == ProfileBase.STATE_CONNECTED){
            peripheralDevice.discoverServices(); // 连接成功获取外围设备的Service
        }else if(connectionState == ProfileBase.STATE_DISCONNECTED){
            BlueTooth_BLE_Manager.setConnect_State(false);
        }
    }

    /**
     *  获取外围设备Service的回调
     * @param status 设备状态
     */
    @Override
    public void servicesDiscoveredEvent(int status) {
        if (status == BlePeripheralDevice.OPERATION_SUCC){
            List<GattService> services = peripheralDevice.getServices();// 获取Service成功后获服务列表
            for (GattService service : services){//匹配到对应的服务
                if (service.getUuid().equals(UUID.fromString(SERVICE_UUID))){
                    this.peripheralDevice.setNotifyCharacteristic(service.getCharacteristic(UUID.fromString(READ_WRITE_NOTIFY)).get(), true);
                    this.service=service;
                    //设置连接标志
                    BlueTooth_BLE_Manager.setConnect_State(true);
                    break;
                }
            }
        }
    }

    /**
     *  外围设备主动向中心设备发送特征值通知时触发回调
     * @param characteristic 返回的characteristic
     */
    @Override
    public void characteristicChangedEvent(GattCharacteristic characteristic) {
        // 更新外围设备发送的数据
        String msg= new String(characteristic.getValue(), StandardCharsets.US_ASCII);
        messages+=msg;
        Matcher matcher = r.matcher(messages);
        while (matcher.find()){
            String m = matcher.group(1);
            messages=messages.substring( matcher.start()+m.length()+2);
            bleBTServiceAbility.Remote.messageLock.lock();
            bleBTServiceAbility.Remote.addMessage(m);
            bleBTServiceAbility.Remote.messageLock.unlock();
        }
    }

    @Override
    public void characteristicWriteEvent(GattCharacteristic characteristic, int ret) {
        if (ret == BlePeripheralDevice.OPERATION_SUCC){
            // 向外围设备写特征值数据成功后的操作
        }
    }

    @Override
    public void characteristicReadEvent(GattCharacteristic characteristic, int ret) {
        if (ret == BlePeripheralDevice.OPERATION_SUCC){
            // 向外围设备读特征值数据成功后的操作
        }
    }

    @Override
    public void descriptorReadEvent(GattDescriptor descriptor, int ret) {
        // 向外围设备读描述值数据成功后的操作
    }

    @Override
    public void descriptorWriteEvent(GattDescriptor descriptor, int ret) {
        // 向外围设备写描述值数据成功后的操作
    }

    @Override
    public void readRemoteRssiEvent(int rssi, int ret) {
        if (ret == BlePeripheralDevice.OPERATION_SUCC){
            // 读取外围设备RSSI值成功后的操作，对端RSSI值为rssi
            ResponseParam responseParamState=new ResponseParam();
            responseParamState.setType("RSSI");
            responseParamState.setNum1(rssi);
            bleBTServiceAbility.Remote.updateToJs(responseParamState);
        }
    }


    /**
     * 向设备写入数据
     * @param message 信息
     */
    public void bleWrite(String message){
        if (this.service==null){
            return;
        }
        GattCharacteristic characteristic = this.service.getCharacteristic(UUID.fromString(READ_WRITE_NOTIFY)).get();
        characteristic.setValue(message.getBytes(StandardCharsets.US_ASCII));
        this.peripheralDevice.writeCharacteristic(characteristic);
    }

    public void readRSSI(){
        if (this.peripheralDevice==null){
            return;
        }
        this.peripheralDevice.readRemoteRssiValue();
    }
}

